﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CrmContacto.Services.Classes;
using System.Configuration;
using System.Threading;
using System.Transactions;
using CrmContacto.Data;
using System.Net.Mail;
using System.IO;
using CrmContacto.Contracts.Enums;
using Web.Framework.Translate;
using CrmContacto.Contracts;
using CrmContacto.Contracts.Services;

namespace CrmContacto.Services.Common
{
    public class CommonCrmTaskManager
    {

        public static void SendEmailToCustomerInThread(ContactoForEmail customer)
        {
            EmailInThread emailInThread = new EmailInThread();
            emailInThread.Contacto = customer;
            emailInThread.ConnectionString = ConfigurationManager.ConnectionStrings["CrmContactoEntities"].ConnectionString;
            emailInThread.ConfigurationsByCompany = ListsCrm.GetCompanyConfigurationKeyValues(customer.EmpresaId);

            ThreadPool.QueueUserWorkItem(SendEmailToCustomer, emailInThread);
        }

        private static void SendEmailToCustomer(object param)
        {
            EmailInThread emailInThread = (EmailInThread)param;
            ContactoForEmail customer = emailInThread.Contacto;
            using (TransactionScope tScope = new TransactionScope())
            {
                using (CrmContactoEntities ctxCrm = new CrmContactoEntities(emailInThread.ConnectionString))
                {
                    List<DbContactoBitacora> contactoBitacoraList = new List<DbContactoBitacora>();
                    DbContacto dbContacto = ctxCrm.DbContactoes.Where(c => c.Id == customer.ContactoId).Single();

                    DbEmpresa dbEmpresa = ctxCrm.DbEmpresas.Where(e => e.Id == customer.EmpresaId).Single();
                    try
                    {
                        SendMail(customer.Email, emailInThread.ConfigurationsByCompany);
                        AgregarBitacoraEmail(contactoBitacoraList, LocalizationProvider.Instance["BitacoraMsgEmailBienvenida"], customer.UserName, DateTime.Now);
                    }
                    catch (Exception ex)
                    {
                        AgregarBitacoraEmail(contactoBitacoraList, LocalizationProvider.Instance["BitacoraMsgEmailBienvenidaFallo"] + ex.Message, customer.UserName, DateTime.Now);
                    }

                    foreach (DbContactoBitacora bitacora in contactoBitacoraList)
                    {
                        dbContacto.ContactoBitacoras.Add(bitacora);
                    }

                    ctxCrm.SaveChanges();
                    tScope.Complete();
                }
            }
        }

        private static void SendMail(string emailAddress, Dictionary<string, string> configurations)
        {
            string subject = configurations[EmpresaConfigurationKeys.MailBienvenidaSubject];
            string body = File.ReadAllText(configurations[EmpresaConfigurationKeys.PathMailBienvenida]);
            string from = configurations[EmpresaConfigurationKeys.MailBienvenidaFrom];
            string replayTo = configurations[EmpresaConfigurationKeys.MailBienvenidaReplyTo];
            string host = configurations[EmpresaConfigurationKeys.MailHost];
            string port = configurations[EmpresaConfigurationKeys.MailPort];

            MailMessage email = new MailMessage();
            email.To.Add(new MailAddress(emailAddress));
            email.Subject = subject;
            email.Body = body;
            email.From = new MailAddress(from);
            email.ReplyToList.Add(new MailAddress(replayTo));
            //email.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure | DeliveryNotificationOptions.OnSuccess;
            email.IsBodyHtml = true;

            SmtpClient client = new SmtpClient();
            client.Host = host;
            client.Port = Convert.ToInt32(port);
            client.DeliveryMethod = SmtpDeliveryMethod.Network;
            client.Send(email);
        }

        private static void AgregarBitacoraEmail(List<DbContactoBitacora> bitacoraList, string mensaje, string userName, DateTime now)
        {
            DbContactoBitacora dbContactoBitacora = new DbContactoBitacora();
            dbContactoBitacora.TipoDeRegistro = (int)TipoRegistroBitacora.Email;
            dbContactoBitacora.Accion = mensaje;
            dbContactoBitacora.AuditUserNameCreacion = userName;
            dbContactoBitacora.AuditFechaCreacion = now;
            bitacoraList.Add(dbContactoBitacora);
        }

        public static void PerformHooksToCustomerInThread(List<Cliente> clienteList, List<ICustomerServiceHook> hookList)
        {
            if (hookList.Count > 0)
            {
                HookInThread hookInThread = new HookInThread();
                hookInThread.ClienteList = clienteList;
                hookInThread.HookList = hookList;
                hookInThread.ConnectionString = ConfigurationManager.ConnectionStrings["CrmContactoEntities"].ConnectionString;
                ThreadPool.QueueUserWorkItem(PerformHooksToCustomer, hookInThread);
            }
        }

        private static void PerformHooksToCustomer(object param)
        {
            HookInThread hookInThread = (HookInThread)param;

            if (hookInThread.HookList.Count > 0)
            {                
                // Por cada uno, intento enviarlo a emblue
                foreach (Cliente cliente in hookInThread.ClienteList)
                {
                    foreach (var hook in hookInThread.HookList)
                    {
                        bool saveOk = hook.AfterSave(cliente);

                        using (TransactionScope tScope = new TransactionScope())
                        {
                            using (CrmContactoEntities ctxCrm = new CrmContactoEntities(hookInThread.ConnectionString))
                            {
                                List<DbContactoBitacora> contactoBitacoraList = new List<DbContactoBitacora>();
                                DbContacto dbContacto = ctxCrm.DbContactoes.Where(c => c.Id == cliente.Id).Single();

                                DbEmpresa dbEmpresa = ctxCrm.DbEmpresas.Where(e => e.Id == cliente.EmpresaId).Single();
                                if(saveOk)
                                {
                                    AgregarBitacoraInterface(contactoBitacoraList, LocalizationProvider.Instance["ServicioExterno.Hook.emBlue.exito"], cliente.UserName, DateTime.Now);
                                }
                                else
                                {
                                    AgregarBitacoraInterface(contactoBitacoraList, LocalizationProvider.Instance["ServicioExterno.Hook.emBlue.falla"], cliente.UserName, DateTime.Now);
                                }

                                foreach (DbContactoBitacora bitacora in contactoBitacoraList)
                                {
                                    dbContacto.ContactoBitacoras.Add(bitacora);
                                }

                                ctxCrm.SaveChanges();
                                tScope.Complete();
                            }
                        }
                    }
                }
            }
        }

        private static void AgregarBitacoraInterface(List<DbContactoBitacora> bitacoraList, string mensaje, string userName, DateTime now)
        {
            DbContactoBitacora dbContactoBitacora = new DbContactoBitacora();
            dbContactoBitacora.TipoDeRegistro = (int)TipoRegistroBitacora.Interface;
            dbContactoBitacora.Accion = mensaje;
            dbContactoBitacora.AuditUserNameCreacion = userName;
            dbContactoBitacora.AuditFechaCreacion = now;
            bitacoraList.Add(dbContactoBitacora);
        }
    }
}
